package com.zeny.express.framework.sso;

import java.util.Date;

import org.apache.commons.lang.time.DateUtils;

/**
 * Token Manager
 * 
 * @author zhuwei
 * @date 2013年9月11日 上午10:44:42
 */
public class TokenManager {

	/**
	 * TODO 默认值从参数配置中获取 会话超时时间
	 */
	private static final int SESSION_TIMEOUT = 30;

	/**
	 * TODO 默认值从参数配置中获取 会话最长时间
	 */
	private static final int SESSION_ONLINE = 24;

	/**
	 * 应用ID
	 */
	private String appId;

	/**
	 * token marshal
	 */
	private TokenMarshal tokenMarshal;

	/**
	 * 生成token
	 * 
	 * @author zhuwei
	 * @date 2013年9月11日 上午10:45:12
	 * @param userId
	 * @return
	 * @throws TokenException
	 */
	public String createToken(String userId) throws TokenException {

		Date createTime = new Date();
		Date expireTime = DateUtils.addMinutes(createTime, SESSION_TIMEOUT);

		Token token = new Token();
		token.setUserId(userId);
		token.setAppId(appId);
		token.setCreateTime(createTime);
		token.setExpireTime(expireTime);

		String tokenId = tokenMarshal.marshal(token);

		return tokenId;
	}

	/**
	 * 获取用户ID
	 * 
	 * @author zhuwei
	 * @date 2013年9月11日 上午10:47:06
	 * @param tokenId
	 * @return
	 * @throws TokenException
	 */
	public String resolveUserId(String tokenId) throws TokenException {

		Date now = new Date();
		Date onlineTime = DateUtils.addHours(now, -SESSION_ONLINE);

		Token token = tokenMarshal.unMarshal(tokenId);

		// TOKEN 过期
		if (token.getExpireTime().before(now)) {
			throw new TokenException(TokenException.SESSION_TIMEOUT);
		}

		// TOKEN 超长
		if (token.getCreateTime().before(onlineTime)) {
			throw new TokenException(TokenException.SESSION_ONLINE);
		}

		// 应用验证
		if (!appId.equals(token.getAppId())) {
			// TODO 应用互相信任
		}

		return token.getUserId();
	}

	/**
	 * 刷新token信息
	 * 
	 * @author zhuwei
	 * @date 2013年9月11日 上午10:47:24
	 * @param tokenId
	 * @return
	 * @throws TokenException
	 */
	public String refreshToken(String tokenId) throws TokenException {

		Token token = tokenMarshal.unMarshal(tokenId);

		String newTokenId = this.createToken(token.getUserId());

		return newTokenId;
	}

	/**
	 * @param tokenMarshal
	 */
	public void setTokenMarshal(TokenMarshal tokenMarshal) {
		this.tokenMarshal = tokenMarshal;
	}

	/**
	 * @param appId
	 */
	public void setAppId(String appId) {
		this.appId = appId;
	}

}
